use async_trait::async_trait;
use futures::Future;
use russh::server::{Auth, Session};
use russh::*;
use russh_keys::*;
use std::io::{stdin, Read};
use std::sync::Arc;
use std::thread;

struct Client {}

#[async_trait]
impl client::Handler for Client {
    type Error = anyhow::Error;

    async fn check_server_key(
        self,
        server_public_key: &key::PublicKey,
    ) -> Result<(Self, bool), Self::Error> {
        println!("check_server_key: {:?}", server_public_key);
        Ok((self, true))
    }

    async fn data(
        self,
        channel: ChannelId,
        data: &[u8],
        session: client::Session,
    ) -> Result<(Self, client::Session), Self::Error> {
        println!(
            "data on channel {:?}: {:?}",
            channel,
            std::str::from_utf8(data)
        );
        Ok((self, session))
    }
}

pub async fn start() {
    let config = russh::client::Config::default();

    let config = Arc::new(config);
    let sh = Client {};

    let mut session = russh::client::connect(config, ("dlzen.com", 22), sh)
        .await
        .unwrap();

    let auth_res = session
        .authenticate_password("web", "web^123_")
        .await
        .unwrap();
    if !auth_res {
        return;
    }

    let mut channel = session.channel_open_session().await.unwrap();
    let terminal_modes = [];
    let _ = channel
        .request_pty(true, "xterm", 80, 20, 100, 100, &terminal_modes)
        .await;
    let _ = channel.request_shell(true).await;
    channel.data(&b"touch heh.txt"[..]).await.unwrap();
    if let Some(msg) = channel.wait().await {
        println!("{:?}", msg)
    }
}
